package com.jhj.provider.bm.config;

import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.jhj.provider.bm.utils.Constants;
import com.jhj.utils.AppResultData;
import com.jhj.utils.sign.JhjSignConfig;
import com.jhj.utils.sign.JhjSignUtils;

/**
 * 全局拦截api访问签名.
 * 
 * @author Angel(QQ:412887952)
 * @version v.0.1
 */
@Aspect
@Configuration

public class ApiSignAspect {
	private Logger logger = LoggerFactory.getLogger(this.getClass());

	ThreadLocal<Long> startTime = new ThreadLocal<Long>();

	/**
	 * 定义一个切入点. 解释下：
	 *
	 * ~ 第一个 * 代表任意修饰符及任意返回值. ~ 第二个 * 任意包名 ~ 第三个 * 代表任意方法. ~ 第四个 * 定义在web包或者子包 ~ 第五个
	 * * 任意方法 ~ .. 匹配任意数量的参数.
	 */
	@Pointcut("execution(* com.jhj.provider.bm.controller.*.*(..))")
	public void ApiSign() {
	}

	@Around("ApiSign()")
	public Object Interceptor(ProceedingJoinPoint pjp) {

		// 接收到请求，记录请求内容
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);
		
		// 验证签名是否有效
		if (!isMultipart && !JhjSignUtils.verifySign(request, JhjSignConfig.appkey, JhjSignConfig.appsecret)) {

			AppResultData<Object> data = new AppResultData<Object>(Constants.SUCCESS_0, "ok", "");
			data.setStatus(Constants.ERROR_999);
			data.setMsg("数据传输错误出错");
			
			// 记录签名出错的信息
			logger.error("URL : " + request.getRequestURL().toString());
			logger.error("HTTP_METHOD : " + request.getMethod());
			logger.error("IP : " + request.getRemoteAddr());
			logger.error("CLASS_METHOD : " + pjp.getSignature().getDeclaringTypeName() + "."
					+ pjp.getSignature().getName());
			logger.error("ARGS : " + Arrays.toString(pjp.getArgs()));
			logger.error("数据传输错误");
			return data;
		}

		Object result = null;
		try {
			result = pjp.proceed();
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return result;

	}
}